﻿using Project362.Users;
using Project362.Collections;
using Project362.Files;
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace Project362
{
    public class SystemClass
    {

        #region Variables

        /// <summary>
        /// The currently logged in user.
        /// </summary>
        private User currentUser;

        /// <summary>
        /// An object that handles all users.
        /// </summary>
        private UserHandler userHandler;

        /// <summary>
        /// A handler for all collections 
        /// </summary>
        private CollectionHandler collectionHandler;

        #endregion
        #region Constructors

        /// <summary>
        /// Creates a new System.
        /// </summary>
        public SystemClass()
        {
            this.currentUser = null;//implies no user is logged in
            this.userHandler = new UserHandler(Directory.GetCurrentDirectory() + "\\UserDictionary");
            this.collectionHandler = new CollectionHandler(Directory.GetCurrentDirectory() + "\\Collections");
        }

        #endregion
        #region Public Methods

        /// <summary>
        /// Attempts to log in the user with the specified user name and password.
        /// </summary>
        /// <param name="userName">User name.</param>
        /// <param name="password">Password.</param>
        /// <returns>True if logged in, false otherwise.</returns>
        public bool login(string userName, string password)
        {
            if (currentUser != null)
                return false;
            currentUser = userHandler.Login(userName, password);
            return currentUser != null;
        }

        /// <summary>
        /// Logs the currently logged in user out.
        /// </summary>
        /// <returns>True if successfully logged out, false otherwise.</returns>
        public bool logout()
        {
            if (currentUser != null)
            {
                currentUser = null;
                return true;
            }
            return false;
        }

        /// <summary>
        /// Attempts to add a new user to the system.
        /// </summary>
        /// <param name="userName">The new user name.</param>
        /// <param name="password">The new user password.</param>
        /// <param name="level">The new user permission level.</param>
        /// <returns>True if successfull, false otherwise.</returns>
        public bool AddUser(string userName, string password, PermissionLevel level)
        {
            // To add the first user you will have to comment this check out for now
            if (currentUser == null || currentUser.Permissions < PermissionLevel.tier4)
                return false;
            return userHandler.AddUser(userName, password, level);
        }

        /// <summary>
        /// Attempts to remove the user with the given name from the system.
        /// </summary>
        /// <param name="userName">The user name.</param>
        /// <returns>True if successfull, false otherwise.</returns>
        public bool RemoveUser(string userName)
        {
            if (currentUser == null || currentUser.Permissions < PermissionLevel.tier4)
                return false;
            return userHandler.RemoveUser(userName);
        }

        /// <summary>
        /// Attempts to change the user permissions of the user specified by the given name to the given
        /// permission level.
        /// </summary>
        /// <param name="userName">The name of the account to change.</param>
        /// <param name="level">The new permission level.</param>
        /// <returns>True if successfull, false otherwise.</returns>
        public bool ChangeUserPermissions(string userName, PermissionLevel level)
        {
            if (currentUser == null || currentUser.Permissions < PermissionLevel.tier4)
                return false;
            return userHandler.ChangeUserPermissions(userName, level);
        }
        /// <summary>
        /// Adds a file to a specific collection.
        /// </summary>
        /// <param name="filename">the name of the file to add</param>
        /// <param name="collection">the name of the collection to add it to</param>
        /// <returns>true if success, false otherwise</returns>
        public bool addFileToCollection(string filename, string collection)
        {
            return collectionHandler.addFileToCollection(filename, collection);
        }
        /// <summary>
        /// Removes a file from a collection, if it exists there
        /// </summary>
        /// <param name="filename">The name of the file to remove</param>
        /// <param name="collection">The collection to remove it from</param>
        /// <returns>true if success, false otherwise</returns>
        public bool removeFileFromCollection(string filename, string collection)
        {
            return collectionHandler.removeFileFromCollection(filename, collection);
        }
        /// <summary>
        /// Gets the files in a collection
        /// </summary>
        /// <param name="collection">The collection to access</param>
        /// <returns>true if success, false otherwise</returns>
        public List<FileClass> getFilesInCollection(string collection)
        {
            return collectionHandler.getFilesInCollection(collection);
        }
        /// <summary>
        /// Moves a file from one collection to another
        /// </summary>
        /// <param name="filename">The file to move</param>
        /// <param name="sourcec">The collection the file is currently in</param>
        /// <param name="destc">The collection to move to</param>
        /// <returns>true if success, false otherwise</returns>
        public bool moveFileBetweenCollections(string filename, string sourcec, string destc)
        {
            return collectionHandler.moveFileBetweenCollections(filename, sourcec, destc);
        }
        /// <summary>
        /// Check the filesystem to see if a certain file exists
        /// </summary>
        /// <param name="filename">Filename to check</param>
        /// <returns>true if success, false otherwise</returns>
        public bool checkFileExists(string filename)
        {
            return File.Exists(filename);
        }
        /// <summary>
        /// Calculate the md5 sum for a file
        /// </summary>
        /// <param name="filename">filename to check</param>
        /// <returns>true if success, false otherwise</returns>
        public string checksumFile(string filename)
        {
            System.Security.Cryptography.MD5 m = System.Security.Cryptography.MD5.Create();
            FileStream f = System.IO.File.OpenRead(filename);
            byte[] data = m.ComputeHash(f);
            StringBuilder s = new StringBuilder();
            foreach (byte datum in data)
            {
                s.Append(datum.ToString("x2"));
            }
            return s.ToString();
        }
        /// <summary>
        /// Adds a new collection to the system
        /// </summary>
        /// <param name="collection">name of the new collection</param>
        /// <returns>true if success, false otherwise</returns>
        public bool addNewCollection(string collection)
        {
            return collectionHandler.addNewCollection(collection);
        }
        /// <summary>
        /// Removes an existing collection from the system
        /// </summary>
        /// <param name="collection">name of collection to remove</param>
        /// <returns>true if success, false otherwise</returns>
        public bool removeCollection(string collection)
        {
            return collectionHandler.removeCollection(collection);
        }
        /// <summary>
        /// Saves all handler data (except user)
        /// </summary>
        /// <returns>true if success, false otherwise</returns>
        public bool SaveAll()
        {
            return this.collectionHandler.saveCollections();
        }

        #endregion

    }
    /// <summary>
    /// The program class represents the View
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
}
